package 状态机.请假demo.machine.impl;

import 状态机.请假demo.event.Event;
import 状态机.请假demo.machine.IStatusMachine;
import 状态机.请假demo.status.Status;

/**
 * 公司规定了年假的请假流程与审批流程
 *
 * 不同的流程+不同的审批意见会得到不同的状态，这些状态是有限个的，实现全部考虑完毕且存放在 Status 类中
 *
 * 所以状态的转移即是更具 status 和 event 选择下一个状态
 */
public class AnnualLeaveStatusMachine implements IStatusMachine {
    @Override
    public Status getNextStatus(Status status, Event event) {
        // java 里面的switch必须加break，否则会造成case穿透，但是下面的代码用的是 return，不必加 break
        switch (status) {

            case PERMIT_SUBMIT:
                //提交假单状态无需审批跳转领导审批中状态
                return Status.LEADER_PERMITTING;

            case LEADER_PERMITTING:
                //领导审批需要审批意见 审批意见不用返回不同的状态
                return getLeaderPermitStatus(event);
            case LEADER_PERMIT_AGREE:
                //领导同意请假，则跳转ceo审批
                return Status.CEO_PERMITING;
            case LEADER_PERMIT_DISAGREE:
                //领导不同意该假单，则请假失败
                return Status.PERMIT_FAIL;
            case LEADER_PERMIT_MODIFY:
                return getLeaderPermitStatus(event);

            case CEO_PERMITING:
                //ceo审批需要审批意见
                return getCEOPermitStatus(event);
            case CEO_PERMIT_AGREE:
                // ceo审批同意 跳转审批通过 请假完成
                return Status.PERMIT_SUCCESS;

            case CEO_PERMIT_DISAGREE:
                //ceo不同意审批 则跳转审批失败
                return Status.PERMIT_FAIL;
            case CEO_PERMIT_MODIFY:
                return getCEOPermitStatus(event);

            default:
                throw new RuntimeException("没有该流程");
        }
    }

    private Status getLeaderPermitStatus(Event event) {
        switch (event) {
            case AGREE:
                //领导审批通过 返回同意该假单
                return Status.LEADER_PERMIT_AGREE;
            case DISSAGREE:
                //领导不同意 则返回领导拒绝改假单状态
                return Status.LEADER_PERMIT_DISAGREE;
            case MODIFY:
                return Status.LEADER_PERMIT_MODIFY;
            default:
                throw new RuntimeException("不支持该Event审批意见");
        }
    }


    private Status getCEOPermitStatus(Event event) {
        switch (event) {
            case AGREE:
                //ceo审批通过 则返回ceo同意该假单
                return Status.CEO_PERMIT_AGREE;
            case DISSAGREE:
                // ceo审批不通过 则返回ceo不同意该假单状态
                return Status.CEO_PERMIT_DISAGREE;
            case MODIFY:
                return Status.CEO_PERMIT_MODIFY;
            default:
                throw new RuntimeException("不支持该Event审批意见");
        }
    }

}
